#ifndef G3_3DD_SPLINE_H
#define G3_3DD_SPLINE_H

#include "GLee/GLee.h"

#include "math/m_vector.h"
#include "file/f_zipstream.h"
#include "file/f_cistream.h"
#include "file/f_filehandler.h"
#include "render/r_frustum.h"
#include "projection.h"
#include "gui/gui_profiler.h"
#include "gui/gui.h"
#include "frame.h"

#include "particle_sys.h"

#include "3dd_lua.h"

#include <list>

#include <boost/thread/mutex.hpp>

//==============================================================================
// Global variables for debugging
//==============================================================================
extern int NumPointsRendered;
extern int NumLinesRendered;
extern int NumSegmentsRendered;
extern int NumSubSplines;
extern bool UseParticles;

//==============================================================================
// GLU Quadric objects that are used to draw the spline
//==============================================================================
extern GLUquadricObj *cylinder;
extern GLUquadricObj *sphere;

//==============================================================================
// Maximal vertex snapping distance
//==============================================================================
extern float Epsilon;

//==============================================================================
// A subspline - a part of the drawn_spline
//==============================================================================
class SUBSPLINE {
    public:
        SUBSPLINE ();
        ~SUBSPLINE ();

		// Affects the thickness of the spline
        float Radius;

		// A list of vertices
        std::list<G3::VEC3F> Points;

        SUBSPLINE& operator=(const SUBSPLINE &sspl);

		void Compile ();

		// Adds a point to the list
        void AddPoint (G3::VEC3F aPoint);

		// Renders a line between two points in the list
        void RenderLine (std::list<G3::VEC3F>::iterator it, int Segments, float aElapsedTime = 0.0f);
		// Renders a point in the list
        void RenderPoint (std::list<G3::VEC3F>::iterator it, int Segments, float aElapsedTime = 0.0f);
		// Renders the whole subspline
        void Render (float aElapsedTime = 0.0f);

		void Filter ();

		void Clear ();

	private:
		// Number of smoothing filter iterations done
		int iterations;

		uint DLID;
		byte Compiling;
};

class DRAWN_SPLINE {
    public:
        DRAWN_SPLINE ();
        ~DRAWN_SPLINE ();

		// The radius that affects the thicknesses of the subsplines
        float Radius;

        G3::PARTICLE_SYSTEM PSys;

		// A list of subsplines
        std::vector<SUBSPLINE> SubSplines;

		// Renders the whole spline
        void Render (float aElapsedTime = 0.0f);

		// Loads the spline from a file
        bool Load (const std::string &aFilename);
		// Saves the spline into a file
        bool Save (const std::string &aFilename);

        boost::mutex m_mutex;
};

//==============================================================================
// The whole drawn spline
//==============================================================================
extern DRAWN_SPLINE Spline;

extern G3::H_TEXTURE hFogMode, hTorusMode;
extern G3::GUI::IMAGE DrawModeIndicator;

void StartNew();
void ToggleDrawMode();

#endif

